
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>

typedef struct TrainInfo
{
	int shift;//班次
	char departure[20];//发车时间
	char start[20];//起点站 
	char end[20];//终点站
	float time;//行车时间
	int load;//额定载客数
	int num;//订票人数 
}TI;

typedef struct TicketManagementSystem
{
	TI* data;//指向所有班次信息的结构体指针
	int size;//有效数据个数 
	int capacity; //容量大小 
}TMS;

void CheckCapacity(TMS* tms)
{
	if (tms->size == tms->capacity)
	{
		int newcapacity = tms->capacity == 0 ? 4 : (tms->capacity + 3);
		tms->capacity = newcapacity;
		TI* tmp = (TI*)realloc(tms->data, sizeof(TI) * newcapacity);
		if (tmp != NULL)
		{
			tms->data = tmp;
		}
	}
}

void LoadTMS(TMS* tms)
{
	FILE* pf = fopen("tms.dat", "r");
	if (pf == NULL)
	{
		return;
	}
	TI tmp = { 0 };
	while (fread(&tmp, sizeof(TI), 1, pf))
	{
		CheckCapacity(tms);
		tms->data[tms->size] = tmp;
		tms->size++;
	}
	fclose(pf);
	pf = NULL;
}

void InitTMS(TMS* tms)//初始化 
{
	tms->data = (TI*)malloc(sizeof(TI));
	tms->capacity = 0;
	tms->size = 0;
	memset(tms->data, 0, sizeof(tms->data));
	LoadTMS(tms);
}


int FindByShift(TMS* tms, int shift)//根据班次号查找
{
	int i = 0;
	for (i = 0; i < tms->size; i++)
	{
		if (tms->data[i].shift == shift)
		{
			return i;
		}
	}
	return -1;
}

int FindByEnd(TMS* tms, char end[])//根据终点站查找
{
	int i = 0;
	for (i = 0; i < tms->size; i++)
	{
		if (0 == strcmp(tms->data[i].end, end))
		{
			return i;
		}
	}
	return -1;
}



void AddTI(TMS* tms)
{
	CheckCapacity(tms);
	printf("请输入班次>");
	scanf("%d", &(tms->data[tms->size].shift));
	printf("请输入发车时间>");
	scanf("%s", (tms->data[tms->size].departure));

	printf("请输入起点站>");
	scanf("%s", (tms->data[tms->size].start));

	printf("请输入终点站>");
	scanf("%s", (tms->data[tms->size].end));

	printf("请输入行车时间>");
	scanf("%f", &(tms->data[tms->size].time));

	printf("请输入额定载量>");
	scanf("%d", &(tms->data[tms->size].load));

	printf("请输入已订票人数>");
	scanf("%d", &(tms->data[tms->size].num));

	tms->size++;

}

void SerachTI(TMS* tms)
{
	int input = 0;
	do
	{
		printf("\n输入1选择根据终点站查找\n");
		printf("\n输入2选择根据班次号查找\n");
		printf("\n输入0退出查找\n");
		scanf("%d", &input);
		switch(input)
		{
		case 1:
			printf("请输入要查找的终点站>");
			char end[20];
			scanf("%s", end);
			int pos = FindByEnd(tms, end);
			if (pos != -1)
			{
				printf("%-10s %-20s %-20s %-20s %-10s %-10s %-10s\n", "班次",
					"发车时间", "起始站", "终点站", "行车时间", "额定载量", "已订票人数");
				printf("%-10d %-20s %-20s %-20s %-10.1f %-10d %-10d\n", tms->data[pos].shift,
					tms->data[pos].departure,
					tms->data[pos].start,
					tms->data[pos].end,
					tms->data[pos].time,
					tms->data[pos].load,
					tms->data[pos].num
				);
			}
			else
			{
				printf("不存在\n");
			}
			break;
		case 2:
			printf("请输入要查找的班次号>");
			int shift = 0;
			scanf("%d", &shift);
			pos = FindByShift(tms, shift);
			if (pos != -1)
			{
				printf("%-10s %-20s %-20s %-20s %-10s %-10s %-10s\n", "班次",
					"发车时间", "起始站", "终点站", "行车时间", "额定载量", "已订票人数");
				printf("%-10d %-20s %-20s %-20s %-10.1f %-10d %-10d\n", tms->data[pos].shift,
					tms->data[pos].departure,
					tms->data[pos].start,
					tms->data[pos].end,
					tms->data[pos].time,
					tms->data[pos].load,
					tms->data[pos].num
				);
			}
			else
			{
				printf("不存在\n");
			}
			break;
		case 0:
			printf("退出成功\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);

}

void ShowTI(TMS* tms)
{
	printf("%-10s %-20s %-20s %-20s %-10s %-10s %-10s\n", "班次",
		"发车时间", "起始站", "终点站", "行车时间", "额定载量", "已订票人数");
	int pos = 0;
	for (pos = 0; pos < tms->size; pos++)
	{
		printf("%-10d %-20s %-20s %-20s %-10.1f %-10d %-10d\n", tms->data[pos].shift,
			tms->data[pos].departure,
			tms->data[pos].start,
			tms->data[pos].end,
			tms->data[pos].time,
			tms->data[pos].load,
			tms->data[pos].num
		);
	}
}

void BuyTicket(TMS* tms)
{
	printf("请输入要前往的终点站>");
	char end[20];
	scanf("%s", end);
	int pos = FindByEnd(tms, end);
	getchar();
	if (pos != -1)
	{
		if (tms->data[pos].num == tms->data[pos].load)
		{
			printf("票数不足\n");
			return;
		}
		printf("请确认目前时间是否超过发车时间，超过则不可购票\n");
		printf("输入Y确认购票，输入N取消购票\n");
		char input;
		scanf("%c", &input);
		if (input == 'Y')
		{
			printf("购票成功\n");
			tms->data[pos].num++;
		}
		else
		{
			printf("取消成功\n");
			return;
		}
	}
	else
	{
		printf("不存在该班次\n");
		return;
	}

}

void RefundTicket(TMS* tms)
{
	printf("请输入要退票的班次>");
	int shift;
	scanf("%d", &shift);
	getchar();
	int pos = FindByShift(tms, shift);
	if (pos != -1)
	{
		printf("请确认目前时间是否超过发车时间，超过则不可退票\n");
		printf("输入Y确认退票，输入N取消退票\n");
		char input;
		scanf("%c", &input);
		if (input == 'Y')
		{
			printf("退票成功\n");
			tms->data[pos].num--;
		}
		else
		{
			printf("取消成功\n");
			return;
		}
	}
	else
	{
		printf("不存在该班次\n");
		return;
	}
}



void SaveTMS(TMS* tms)
{
	FILE* pf = fopen("tms.dat", "w");
	int i;
	for (i = 0; i < tms->size; i++)
	{
		fwrite(tms->data + i, sizeof(TI), 1, pf);
	}
	fclose(pf);
	pf = NULL;
}

enum Choice
{
	EXIT,
	ADD,
	SHOW,
	SEARCH,
	PURCHASE,
	REFUND
};

void menu()
{
	printf("*********************\n");
	printf("*** 1.add  2.show***\n");
	printf("***   3.search   ***\n");
	printf("***   4.purchase  ***\n");
	printf("***   5.refund    ***\n");
	printf("***   0.exit      ***\n");
	printf("*********************\n");
}

int main()
{
	TMS tms;
	InitTMS(&tms);
	int input = 0;
	do
	{
		menu();
		printf("\n请输入您的选项>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddTI(&tms);
			break;
		case SHOW:
			ShowTI(&tms);
			break;
		case SEARCH:
			SerachTI(&tms);
			break;
		case PURCHASE:
			BuyTicket(&tms);
			break;
		case REFUND:
			RefundTicket(&tms);
			break;
		case EXIT:
			SaveTMS(&tms);
			printf("退出成功\n");
			break;
		default:
			printf("输入错误\n");
			break;
		}
	} while (input);

	return 0;
}


